﻿/***********************************************************************************\
| Copyright (c) 2011, Bashar Al-Rawi                                                |
| All rights reserved.                                                              |
|                                                                                   |
| Redistribution and use in source and binary forms, with or without                |
| modification, are permitted provided that the following conditions are met:       |
|    * Redistributions of source code must retain the above copyright               |
|      notice, this list of conditions and the following disclaimer.                |
|    * Redistributions in binary form must reproduce the above copyright            |
|      notice, this list of conditions and the following disclaimer in the          |
|      documentation and/or other materials provided with the distribution.         |
|    * Neither the name of the <organization> nor the                               |
|      names of its contributors may be used to endorse or promote products         |
|      derived from this software without specific prior written permission.        |
|                                                                                   |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     |
| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            |
| DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY                |
| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        |
| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      |
| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND       |
| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT        |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     |
| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      |
\***********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Resources;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using System.Windows.Data;
using System.Diagnostics;
using System.Reflection;

namespace Arabic.Controls
{
 
    public partial class Key : UserControl
    {
        internal static Brush BtnBrush;
        private bool isTouchUp;
        private static SoundEffect effectNormal;
        private static SoundEffect effectSpecial;
        private static SoundEffect effectSpacebar;
        
        public delegate void KeyDownEventHandler(object sender, KbdEventArgs e);
        public new event KeyDownEventHandler KeyDown;
        public new event KeyDownEventHandler KeyUp;
        
        internal Key()
        {
            InitializeComponent();
        }

        internal Key(KeyboardKey keyModel)
        {
            this.DataContext = keyModel;
            InitializeComponent();
        }

        static Key()
        {
            if (ApplicationGlobals.IsDarkTheme)
            {
                BtnBrush = new SolidColorBrush(System.Windows.Media.Color.FromArgb(255, 63, 63, 63));
            }
            else
            {
                BtnBrush = ApplicationGlobals.BgBrush;
            }
            Application.Current.Resources.Add("PhoneButtonColor", BtnBrush);
            Assembly assembly = typeof(Key).Assembly;
            
            using (var stream = assembly.GetManifestResourceStream("Arabic.Controls.Sounds.KbdKeyTap.wav"))
            {
                effectNormal = SoundEffect.FromStream(stream);
            }
            using (var stream = assembly.GetManifestResourceStream("Arabic.Controls.Sounds.KbdFunction.wav"))
            {
                effectSpecial = SoundEffect.FromStream(stream);
            }
            using (var stream = assembly.GetManifestResourceStream("Arabic.Controls.Sounds.KbdSpacebar.wav"))
            {
                effectSpacebar = SoundEffect.FromStream(stream);
            }
            FrameworkDispatcher.Update();
            
            
        }

        internal void PlaySound()
        {
            KeyboardKey k = this.DataContext as KeyboardKey;
            
            if (SIP.Instance.IsSpacebar(k))
            {
                effectSpacebar.Play(0.6f * SoundEffect.MasterVolume, 0f, 0f);
            }
            else if (SIP.Instance.IsSpecialKey(k))
            {
                effectSpecial.Play(0.6f * SoundEffect.MasterVolume, 0f, 0f);
            }
            else
            {
                effectNormal.Play(0.6f * SoundEffect.MasterVolume, 0f, 0f);
            }
            
        }

        private void button1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.rectangle.Fill = ApplicationGlobals.FgBrush;
            this.textBlock.Foreground = ApplicationGlobals.BgBrush;
            PlaySound();
            KeyDown(this, null);
        }

        private void button_MouseLeave(object sender, MouseEventArgs e)
        {
            Touch.FrameReported -= Touch_FrameReported;
            this.rectangle.Fill = BtnBrush;
            this.textBlock.Foreground = ApplicationGlobals.FgBrush;
            KbdEventArgs keyArgs = null;
            KeyboardKey k = (KeyboardKey)this.DataContext;
            k.SwitchColors();

            // there is no way to differentiate between whether the mouse left the button
            // or the mouse was released while on top of button. Use Touch APIs to determine that
            if (isTouchUp)
            {
                keyArgs = new KbdEventArgs(k.KeyCode, k.PlatformkeyCode);      
            }
            isTouchUp = false;
            KeyUp(this, keyArgs);
        }

        private void button_MouseEnter(object sender, MouseEventArgs e)
        {
            Touch.FrameReported += Touch_FrameReported;
            
            isTouchUp = false;
            this.rectangle.Fill = ApplicationGlobals.FgBrush;
            this.textBlock.Foreground = ApplicationGlobals.BgBrush;
            KeyboardKey k = this.DataContext as KeyboardKey;
            k.SwitchColors();
            KbdEventArgs keyArgs = new KbdEventArgs(k.KeyCode, k.PlatformkeyCode);
            KeyDown(this, keyArgs);

        }

        private void Touch_FrameReported (object sender, TouchFrameEventArgs e)
        {
            try
            {
                if (e.GetPrimaryTouchPoint(this).Action == TouchAction.Up)
                {
                    isTouchUp = true;
                }
            }
            catch (ArgumentException ex)
            {
                isTouchUp = true;
            }

        }

        
    }
}
